home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / DirectSound / SoundFX / soundfx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  56.6 KB  |  1,411 lines

  1. //-----------------------------------------------------------------------------
  2. // File: SoundFX.cpp
  3. //
  4. // Desc: Sample to demonstrate soundFX and parameters in directX
  5. //
  6. // Copyright ( c ) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #include <commdlg.h>
  10. #include "resource.h"
  11.  
  12.  
  13.  
  14.  
  15.  
  16. //-----------------------------------------------------------------------------
  17. // Function-prototypes
  18. //-----------------------------------------------------------------------------
  19. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg,  WPARAM wParam, LPARAM lParam );
  20. VOID    OnInitDialog( HWND hDlg );
  21. VOID    OnTimer( HWND hDlg );
  22. VOID    OnOpenSoundFile( HWND hDlg );
  23. HRESULT OnPlaySound( HWND hDlg );
  24. VOID    OnEffectChanged( HWND hDlg );
  25. HRESULT ValidateWaveFile( HWND hDlg, TCHAR* strFileName );
  26. void    EnablePlayUI( HWND hDlg, BOOL bEnable );
  27.  
  28. VOID    LoadParameterUI ( HWND hDlg, DWORD dwFXType );
  29. VOID    ResetParameterUI ( HWND hDlg );
  30.  
  31.  
  32.  
  33.  
  34. //-----------------------------------------------------------------------------
  35. // Name: enum ESFXType
  36. // Desc: each is a unique identifier mapped to a DirectSoundFX
  37. //-----------------------------------------------------------------------------
  38. enum ESFXType
  39. {
  40.     eSFX_chorus = 0,
  41.     eSFX_compressor,
  42.     eSFX_distortion,
  43.     eSFX_echo,
  44.     eSFX_flanger,
  45.     eSFX_gargle,
  46.     eSFX_parameq,
  47.     eSFX_reverb,
  48.  
  49.     // number of enumerated effects
  50.     eNUM_SFX
  51. };
  52.  
  53.  
  54.  
  55.  
  56. //-----------------------------------------------------------------------------
  57. // Name: class CSoundFXManager
  58. // Desc: Takes care of effects for one DirectSoundBuffer
  59. //-----------------------------------------------------------------------------
  60. class CSoundFXManager
  61. {
  62. public:
  63.     CSoundFXManager( );
  64.     ~CSoundFXManager( );
  65.  
  66. public: // interface
  67.     HRESULT Initialize ( LPDIRECTSOUNDBUFFER lpDSB, BOOL bLoadDefaultParamValues );
  68.     HRESULT UnInitialize ( );
  69.  
  70.     HRESULT SetFXEnable( DWORD esfxType );
  71.     HRESULT ActivateFX( );
  72.     HRESULT DisableAllFX( );
  73.     HRESULT LoadCurrentFXParameters( );
  74.  
  75. public: // members
  76.     LPDIRECTSOUNDFXCHORUS8      m_lpChorus;
  77.     LPDIRECTSOUNDFXCOMPRESSOR8  m_lpCompressor;
  78.     LPDIRECTSOUNDFXDISTORTION8  m_lpDistortion;
  79.     LPDIRECTSOUNDFXECHO8        m_lpEcho;
  80.     LPDIRECTSOUNDFXFLANGER8     m_lpFlanger;
  81.     LPDIRECTSOUNDFXGARGLE8      m_lpGargle;
  82.     LPDIRECTSOUNDFXPARAMEQ8     m_lpParamEq;
  83.     LPDIRECTSOUNDFXWAVESREVERB8 m_lpReverb;
  84.  
  85.     DSFXChorus                  m_paramsChorus;
  86.     DSFXCompressor              m_paramsCompressor;
  87.     DSFXDistortion              m_paramsDistortion;
  88.     DSFXEcho                    m_paramsEcho;
  89.     DSFXFlanger                 m_paramsFlanger;
  90.     DSFXGargle                  m_paramsGargle;
  91.     DSFXParamEq                 m_paramsParamEq;
  92.     DSFXWavesReverb             m_paramsReverb;
  93.  
  94.     LPDIRECTSOUNDBUFFER8        m_lpDSB8;
  95.  
  96. protected:
  97.     DSEFFECTDESC                m_rgFxDesc[eNUM_SFX];
  98.     const GUID *                m_rgRefGuids[eNUM_SFX];
  99.     LPVOID *                    m_rgPtrs[eNUM_SFX];
  100.     BOOL                        m_rgLoaded[eNUM_SFX];
  101.     DWORD                       m_dwNumFX;
  102.  
  103.     HRESULT EnableGenericFX( GUID guidSFXClass, REFGUID rguidInterface, LPVOID * ppObj );
  104.     HRESULT LoadDefaultParamValues( );
  105. };
  106.  
  107.  
  108.  
  109.  
  110. //-----------------------------------------------------------------------------
  111. // defines and global variables
  112. //-----------------------------------------------------------------------------
  113. #define             DEFAULT_SLIDER_MIN          1
  114. #define             DEFAULT_SLIDER_MAX          0x7FFFFF
  115. #define             DEFAULT_SLIDER_INC          DEFAULT_SLIDER_MAX >> 11
  116.  
  117. CSoundManager *     g_lpSoundManager = NULL;
  118. CSound *            g_lpSound = NULL;
  119. CSoundFXManager *   g_lpFXManager = NULL;
  120. HINSTANCE           g_hInst = NULL;
  121. TCHAR               g_tszFilename[MAX_PATH];
  122. DWORD               g_dwCurrentFXType           = eSFX_chorus;
  123.  
  124. const TCHAR *       g_tszFXNames[] = { L"Chorus", L"Compressor", L"Distortion", L"Echo",
  125.                                        L"Flanger", L"Gargle", L"Param Eq", L"Reverb" };
  126.  
  127.  
  128.  
  129.  
  130. //-----------------------------------------------------------------------------
  131. // Name: WinMain()
  132. // Desc: Entry point for the application.  Since we use a simple dialog for
  133. //       user interaction we don't need to pump messages.
  134. //-----------------------------------------------------------------------------
  135. INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, INT nCmdShow )
  136. {
  137.     g_hInst = hInst;
  138.  
  139.     CoInitialize( NULL );
  140.  
  141.     // Init the common control dll
  142.     InitCommonControls();
  143.  
  144.     // Display the main dialog box.
  145.     DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );
  146.  
  147.     CoUninitialize();
  148.  
  149.     return TRUE;
  150. }
  151.  
  152.  
  153.  
  154.  
  155. //-----------------------------------------------------------------------------
  156. // Name: MainDlgProc()
  157. // Desc: Handles dialog messages
  158. //-----------------------------------------------------------------------------
  159. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  160. {
  161.     HRESULT hr;
  162.  
  163.     switch( msg )
  164.     {
  165.         case WM_COMMAND:
  166.             switch( LOWORD(wParam) )
  167.             {
  168.                 case IDOK:
  169.                 case IDCANCEL:
  170.                     EndDialog( hDlg, IDOK );
  171.                     break;
  172.  
  173.                 case IDC_BUTTON_OPEN:
  174.                     OnOpenSoundFile( hDlg );
  175.                     break;
  176.  
  177.                 case IDC_BUTTON_PLAY:
  178.                     if( FAILED( hr = OnPlaySound( hDlg ) ) )
  179.                     {
  180.                         DXTRACE_ERR_MSGBOX( TEXT("OnPlaySound"), hr );
  181.                         MessageBox( hDlg, L"Error playing DirectSound buffer."
  182.                                     L"Sample will now exit.", L"DirectSound Sample",
  183.                                     MB_OK | MB_ICONERROR );
  184.                         EndDialog( hDlg, IDABORT );
  185.                     }
  186.                     break;
  187.  
  188.                 case IDC_BUTTON_STOP:
  189.                     if( g_lpSound )
  190.                     {
  191.                         g_lpSound->Stop();
  192.                         g_lpSound->Reset();
  193.                     }
  194.                     g_lpFXManager->DisableAllFX( );
  195.                     EnablePlayUI( hDlg, TRUE );
  196.                     SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Sound stopped.") );
  197.                     break;
  198.  
  199.                 case IDC_RADIO_TRIANGLE:
  200.                 case IDC_RADIO_SQUARE:
  201.                 case IDC_RADIO_SINE:
  202.                 case IDC_RADIO_NEG_180:
  203.                 case IDC_RADIO_NEG_90:
  204.                 case IDC_RADIO_ZERO:
  205.                 case IDC_RADIO_90:
  206.                 case IDC_RADIO_180:
  207.                     OnEffectChanged( hDlg );
  208.                     break;
  209.  
  210.                 default:
  211.                     if( LOWORD( wParam ) >= IDC_RADIO_CHORUS &&
  212.                         LOWORD( wParam ) <= IDC_RADIO_REVERB )
  213.                     {
  214.                         g_dwCurrentFXType = LOWORD( wParam ) - IDC_RADIO_CHORUS;
  215.                         LoadParameterUI( hDlg, g_dwCurrentFXType );
  216.                     }
  217.                     else
  218.                         return FALSE; // Didn't handle message
  219.             }
  220.             break;
  221.  
  222.         case WM_TIMER:
  223.             OnTimer( hDlg );
  224.             break;
  225.  
  226.         case WM_INITDIALOG:
  227.             OnInitDialog( hDlg );
  228.             break;
  229.  
  230.         case WM_NOTIFY:
  231.         {
  232.             //LPNMHDR pnmh = ( LPNMHDR ) lParam;
  233.             //if( pnmh->code >= IDC_SLIDER1 && pnmh->code <= IDC_SLIDER6 )
  234.             //{
  235.                 OnEffectChanged( hDlg );
  236.             //}
  237.             break;
  238.         }
  239.         case WM_DESTROY:
  240.             // Cleanup everything
  241.             KillTimer( hDlg, 1 );
  242.             SAFE_DELETE( g_lpFXManager );
  243.             SAFE_DELETE( g_lpSound );
  244.             SAFE_DELETE( g_lpSoundManager );
  245.             break;
  246.  
  247.         default:
  248.             return FALSE; // Didn't handle message
  249.     }
  250.  
  251.     return TRUE; // Handled message
  252. }
  253.  
  254.  
  255.  
  256.  
  257. //-----------------------------------------------------------------------------
  258. // Name: OnInitDialog()
  259. // Desc: Initializes the dialogs (sets up UI controls, etc.)
  260. //-----------------------------------------------------------------------------
  261. VOID OnInitDialog( HWND hDlg )
  262. {
  263.     HRESULT hr;
  264.  
  265.     // Load the icon - will be set during WM_INITDIALOG
  266.     HICON hIcon = LoadIcon( g_hInst, MAKEINTRESOURCE( IDI_ICON ) );
  267.     PostMessage( hDlg, WM_SETICON, ICON_BIG, ( LPARAM ) hIcon );
  268.     PostMessage( hDlg, WM_SETICON, ICON_SMALL, ( LPARAM ) hIcon );
  269.  
  270.     // Create a static IDirectSound in the CSound class.
  271.     // Set coop level to DSSCL_PRIORITY, and set primary buffer
  272.     // format to stereo, 22kHz and 16-bit output.
  273.     g_lpSoundManager = new CSoundManager();
  274.     g_lpFXManager = new CSoundFXManager();
  275.  
  276.     if( NULL == g_lpSoundManager ||
  277.         NULL == g_lpFXManager )
  278.     {
  279.         DXTRACE_ERR_MSGBOX( TEXT("Initialize"), E_OUTOFMEMORY );
  280.         EndDialog( hDlg, IDABORT );
  281.         return;
  282.     }
  283.  
  284.  
  285.     if( FAILED( hr = g_lpSoundManager->Initialize( hDlg, DSSCL_PRIORITY ) ) )
  286.     {
  287.         DXTRACE_ERR_MSGBOX( TEXT("Initialize"), hr );
  288.         MessageBox( hDlg, L"Error initializing DirectSound.  Sample will now exit.",
  289.                             L"DirectSound Sample", MB_OK | MB_ICONERROR );
  290.         EndDialog( hDlg, IDABORT );
  291.         return;
  292.     }
  293.  
  294.     if( FAILED( hr = g_lpSoundManager->SetPrimaryBufferFormat( 2, 22050, 16 ) ) )
  295.     {
  296.         DXTRACE_ERR_MSGBOX( TEXT("SetPrimaryBufferFormat"), hr );
  297.         MessageBox( hDlg, L"Error initializing DirectSound.  Sample will now exit.",
  298.                           L"DirectSound Sample", MB_OK | MB_ICONERROR );
  299.         EndDialog( hDlg, IDABORT );
  300.         return;
  301.     }
  302.  
  303.     // Create a timer, so we can check for when the soundbuffer is stopped
  304.     SetTimer( hDlg, 0, 250, NULL );
  305.  
  306.     // Load default wave file
  307.     TCHAR strFile[MAX_PATH];
  308.     if( GetWindowsDirectory( strFile, MAX_PATH ) == 0 )
  309.         return;
  310.     wcscat( strFile, L"\\media\\ding.wav" );
  311.  
  312.     // Make sure wave file is valid and supported
  313.     if( FAILED( hr = ValidateWaveFile( hDlg, strFile ) ) )
  314.     {
  315.         // Set the UI controls
  316.         SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") );
  317.         SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("No file loaded.") );
  318.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY ), FALSE );
  319.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP ), FALSE );
  320.         return;
  321.     }
  322.  
  323.     if( SUCCEEDED( hr = g_lpSoundManager->Create( &g_lpSound, g_tszFilename,
  324.                                                   DSBCAPS_CTRLFX, GUID_NULL ) ) )
  325.     {
  326.         g_lpFXManager->Initialize( g_lpSound->GetBuffer( 0 ), TRUE );
  327.  
  328.         // un-attach the sound buffer
  329.         g_lpFXManager->UnInitialize( );
  330.  
  331.         SAFE_DELETE( g_lpSound );
  332.     }
  333.  
  334.     // set UI defaults
  335.     CheckDlgButton( hDlg, IDC_CHECK_LOOP, BST_CHECKED );
  336.     CheckRadioButton( hDlg, IDC_RADIO_CHORUS, IDC_RADIO_REVERB, IDC_RADIO_CHORUS );
  337.     LoadParameterUI( hDlg, g_dwCurrentFXType );
  338.     EnablePlayUI( hDlg, TRUE );
  339. }
  340.  
  341.  
  342.  
  343.  
  344. //-----------------------------------------------------------------------------
  345. // Name: OnPlaySound()
  346. // Desc: User hit the "Play" button
  347. //-----------------------------------------------------------------------------
  348. HRESULT OnPlaySound( HWND hDlg )
  349. {
  350.     HRESULT hr;
  351.     DWORD   dwCreationFlags;
  352.     DWORD   dwLooped;
  353.     DWORD   i;
  354.     BOOL bLooped        = ( IsDlgButtonChecked( hDlg, IDC_CHECK_LOOP ) == BST_CHECKED );
  355.  
  356.     // We would only use CTRLFX control on dsound buffer
  357.     dwCreationFlags = DSBCAPS_CTRLFX;
  358.  
  359.     // Free any previous sound and FXs
  360.     g_lpFXManager->DisableAllFX( );
  361.     SAFE_DELETE( g_lpSound );
  362.  
  363.     // Since the user can change the focus before the sound is played,
  364.     // we need to create the sound buffer every time the play button is pressed
  365.  
  366.     // Load the wave file into a DirectSound buffer
  367.     if( FAILED( hr = g_lpSoundManager->Create( &g_lpSound, g_tszFilename,
  368.                                                dwCreationFlags, GUID_NULL ) ) )
  369.     {
  370.         // Not a critical failure, so just update the status
  371.         DXTRACE_ERR( TEXT("Create"), hr );
  372.  
  373.         if( hr == DSERR_BUFFERTOOSMALL )
  374.         {
  375.             // DSERR_BUFFERTOOSMALL will be returned if the buffer is
  376.             // less than DSBSIZE_FX_MIN (150ms) and the buffer is created
  377.             // with DSBCAPS_CTRLFX.
  378.             SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Wave file is too short (less than 150ms) for effect processing.") );
  379.         }
  380.         else
  381.         {
  382.             SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Could not create sound buffer.") );
  383.         }
  384.  
  385.         return S_FALSE;
  386.     }
  387.  
  388.     g_lpFXManager->Initialize( g_lpSound->GetBuffer( 0 ), FALSE );
  389.     for( i = IDC_CHECK_CHORUS; i <= IDC_CHECK_REVERB; i++ )
  390.     {
  391.         if( IsDlgButtonChecked( hDlg, i ) == BST_CHECKED )
  392.             g_lpFXManager->SetFXEnable( i - IDC_CHECK_CHORUS );
  393.     }
  394.  
  395.  
  396.     if( FAILED( hr = g_lpFXManager->ActivateFX( ) ) )
  397.         goto LFail;
  398.     if( FAILED( hr = g_lpFXManager->LoadCurrentFXParameters( ) ) )
  399.         goto LFail;
  400.  
  401.     // Play the sound
  402.     dwLooped = bLooped ? DSBPLAY_LOOPING : 0L;
  403.     if( FAILED( hr = g_lpSound->Play( 0, dwLooped ) ) )
  404.         return DXTRACE_ERR( TEXT("Play"), hr );
  405.  
  406.     // Update the UI controls to show the sound as playing
  407.     EnablePlayUI( hDlg, FALSE );
  408.     SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Sound playing.") );
  409.  
  410.     return S_OK;
  411.  
  412. LFail:
  413.     // Update the UI controls to show the sound effects could not be loaded
  414.     SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Effects creation failed.  Some effects may not support 8-bit wave files.") );
  415.  
  416.     return S_OK;
  417. }
  418.  
  419.  
  420.  
  421.  
  422. //-----------------------------------------------------------------------------
  423. // Name: OnOpenSoundFile()
  424. // Desc: Called when the user requests to open a sound file
  425. //-----------------------------------------------------------------------------
  426. VOID OnOpenSoundFile( HWND hDlg )
  427. {
  428.     static TCHAR strFileName[MAX_PATH] = TEXT("");
  429.     static TCHAR strPath[MAX_PATH] = TEXT("");
  430.  
  431.     // Setup the OPENFILENAME structure
  432.     OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL,
  433.                          TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL,
  434.                          0, 1, strFileName, MAX_PATH, NULL, 0, strPath,
  435.                          TEXT("Open Sound File"),
  436.                          OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0,
  437.                          TEXT(".wav"), 0, NULL, NULL };
  438.  
  439.     // Get the default media path (something like C:\WINDOWS\MEDIA)
  440.     if( '\0' == strPath[0] )
  441.     {
  442.         if( GetWindowsDirectory( strPath, MAX_PATH ) != 0 )
  443.         {
  444.             if( wcscmp( &strPath[wcslen(strPath)], TEXT("\\") ) )
  445.                 wcscat( strPath, TEXT("\\") );
  446.             wcscat( strPath, TEXT("MEDIA") );
  447.         }
  448.     }
  449.  
  450.     // Update the UI controls to show the sound as loading a file
  451.     EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY ), FALSE );
  452.     EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP ), FALSE );
  453.     SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Loading file...") );
  454.  
  455.     // Stop playing the current sound and disable the effects
  456.     g_lpFXManager->DisableAllFX( );
  457.  
  458.     // Display the OpenFileName dialog. Then, try to load the specified file
  459.     if( TRUE != GetOpenFileName( &ofn ) )
  460.     {
  461.         // Set the UI controls
  462.         SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") );
  463.         SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("No file loaded.") );
  464.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY ), FALSE );
  465.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP ), FALSE );
  466.         return;
  467.     }
  468.  
  469.     SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") );
  470.  
  471.     // Make sure wave file is valid and supported
  472.     if( FAILED( ValidateWaveFile( hDlg, strFileName ) ) )
  473.     {
  474.         // Set the UI controls
  475.         SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") );
  476.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY ), FALSE );
  477.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP ), FALSE );
  478.         return;
  479.     }
  480.  
  481.     EnablePlayUI( hDlg, TRUE );
  482.  
  483.     // Remember the path for next time
  484.     wcscpy( strPath, strFileName );
  485.     WCHAR* strLastSlash = wcsrchr( strPath, '\\' );
  486.     if( strLastSlash )
  487.         strLastSlash[0] = '\0';
  488. }
  489.  
  490.  
  491.  
  492.  
  493. //-----------------------------------------------------------------------------
  494. // Name: OnTimer()
  495. // Desc: When we think the sound is playing this periodically checks to see if
  496. //       the sound has stopped.  If it has then updates the dialog.
  497. //-----------------------------------------------------------------------------
  498. VOID OnTimer( HWND hDlg )
  499. {
  500.     if( IsWindowEnabled( GetDlgItem( hDlg, IDC_BUTTON_STOP ) ) )
  501.     {
  502.         // We think the sound is playing, so see if it has stopped yet.
  503.         if( g_lpSound && !g_lpSound->IsSoundPlaying() )
  504.         {
  505.             // Update the UI controls to show the sound as stopped
  506.             EnablePlayUI( hDlg, TRUE );
  507.             SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Sound stopped.") );
  508.         }
  509.     }
  510. }
  511.  
  512.  
  513.  
  514.  
  515. //-----------------------------------------------------------------------------
  516. // Name: EnablePlayUI()
  517. // Desc: Enables or disables the Play UI controls
  518. //-----------------------------------------------------------------------------
  519. VOID EnablePlayUI( HWND hDlg, BOOL bEnable )
  520. {
  521.     if( bEnable )
  522.     {
  523.         EnableWindow( GetDlgItem( hDlg, IDC_CHECK_LOOP      ), TRUE );
  524.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY     ), TRUE );
  525.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP     ), FALSE );
  526.         SetFocus(     GetDlgItem( hDlg, IDC_BUTTON_PLAY )   );
  527.     }
  528.     else
  529.     {
  530.         EnableWindow( GetDlgItem( hDlg, IDC_CHECK_LOOP      ), FALSE );
  531.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY     ), FALSE );
  532.         EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP     ), TRUE );
  533.         SetFocus(     GetDlgItem( hDlg, IDC_BUTTON_STOP )   );
  534.     }
  535.  
  536.     for( DWORD i = IDC_CHECK_CHORUS; i <= IDC_CHECK_REVERB; i++ )
  537.         EnableWindow( GetDlgItem( hDlg, i ), bEnable );
  538. }
  539.  
  540.  
  541.  
  542.  
  543. //-----------------------------------------------------------------------------
  544. // Name: ResetParameterUI( )
  545. // Desc: Blanks the paramter UI
  546. //-----------------------------------------------------------------------------
  547. VOID ResetParameterUI( HWND hwndDlg )
  548. {
  549.     HWND hwndItem;
  550.     DWORD i;
  551.  
  552.     for ( i = IDC_PARAM_NAME1; i <= IDC_PARAM_MAX6; i++ )
  553.     {
  554.         hwndItem = GetDlgItem( hwndDlg, i );
  555.         SendMessage( hwndItem, WM_SETTEXT, 0, ( LPARAM ) TEXT( "- - -" ) );
  556.         EnableWindow( hwndItem, FALSE );
  557.     }
  558.  
  559.     for ( i = IDC_SLIDER1; i <= IDC_SLIDER6; i += 5 )
  560.     {
  561.         PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETRANGEMIN, FALSE, DEFAULT_SLIDER_MIN );
  562.         PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETRANGEMAX, FALSE, DEFAULT_SLIDER_MAX );
  563.         PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETLINESIZE, FALSE, DEFAULT_SLIDER_INC );
  564.         PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETPOS, TRUE, 0 );
  565.     }
  566.  
  567.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_TRIANGLE ), FALSE );
  568.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SQUARE ), FALSE );
  569.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SINE ), FALSE );
  570.     EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_WAVEFORM ), FALSE );
  571.  
  572.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_NEG_180 ), FALSE );
  573.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_NEG_90 ), FALSE );
  574.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_ZERO ), FALSE );
  575.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_90 ), FALSE );
  576.     EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_180 ), FALSE );
  577.     EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_PHASE ), FALSE );
  578. }
  579.  
  580.  
  581.  
  582.  
  583. //-----------------------------------------------------------------------------
  584. // Name: EnableSingleParameter
  585. // Desc:
  586. //-----------------------------------------------------------------------------
  587. VOID EnableSingleParameter( HWND hwndDlg, DWORD resID )
  588. {
  589.     for ( DWORD i = resID; i < resID + 5; i++ )
  590.         EnableWindow( GetDlgItem( hwndDlg, i ), TRUE );
  591. }
  592.  
  593.  
  594.  
  595.  
  596. //-----------------------------------------------------------------------------
  597. // Name: PosSlider
  598. // Desc:
  599. //-----------------------------------------------------------------------------
  600. VOID PosSlider( HWND hwndDlg, DWORD dwSlider, FLOAT val, FLOAT min, FLOAT max,
  601.                 FLOAT fSliderInc )
  602. {
  603.     HWND hwndSlider = GetDlgItem( hwndDlg, dwSlider );
  604.  
  605.     LONG lSliderInc = (LONG) ( (fSliderInc / (max - min)) * DEFAULT_SLIDER_MAX );
  606.     PostMessage( hwndSlider, TBM_SETLINESIZE, FALSE, lSliderInc );
  607.  
  608.     FLOAT res = ( val - min ) / ( max - min );
  609.     if( res < 0.0f )
  610.         res = 0.0f;
  611.     else if( res > 1.0f )
  612.         res = 1.0f;
  613.  
  614.     LONG pos = (LONG) ( res * DEFAULT_SLIDER_MAX );
  615.     PostMessage( hwndSlider, TBM_SETPOS, TRUE, pos );
  616. }
  617.  
  618.  
  619.  
  620.  
  621. //-----------------------------------------------------------------------------
  622. // Name: LoadSingleParameter
  623. // Desc:
  624. //-----------------------------------------------------------------------------
  625. VOID LoadSingleParameter( HWND hwndDlg, DWORD id, const TCHAR * tszName, FLOAT val,
  626.                           FLOAT min, FLOAT max, FLOAT fSliderInc = 0.1f,
  627.                           DWORD dwPrecision = 1 )
  628. {
  629.     TCHAR tszstr[MAX_PATH];
  630.  
  631.     // wet dry mix
  632.     EnableSingleParameter( hwndDlg, id );
  633.     SendMessage( GetDlgItem( hwndDlg, id ), WM_SETTEXT, 0, ( LPARAM ) tszName );
  634.  
  635.     switch( dwPrecision )
  636.     {
  637.         case 0:
  638.             swprintf( tszstr, L"%.0f", val );
  639.             SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  640.             swprintf( tszstr, L"%.0f", min );
  641.             SendMessage( GetDlgItem( hwndDlg, id + 3 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  642.             swprintf( tszstr, L"%.0f", max );
  643.             SendMessage( GetDlgItem( hwndDlg, id + 4 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  644.             break;
  645.         case 1:
  646.             swprintf( tszstr, L"%.1f", val );
  647.             SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  648.             swprintf( tszstr, L"%.1f", min );
  649.             SendMessage( GetDlgItem( hwndDlg, id + 3 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  650.             swprintf( tszstr, L"%.1f", max );
  651.             SendMessage( GetDlgItem( hwndDlg, id + 4 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  652.             break;
  653.         default:
  654.         case 2:
  655.             swprintf( tszstr, L"%.2f", val );
  656.             SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  657.             swprintf( tszstr, L"%.2f", min );
  658.             SendMessage( GetDlgItem( hwndDlg, id + 3 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  659.             swprintf( tszstr, L"%.2f", max );
  660.             SendMessage( GetDlgItem( hwndDlg, id + 4 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  661.             break;
  662.     }
  663.  
  664.     PosSlider( hwndDlg, id + 2, val, min, max, fSliderInc );
  665. }
  666.  
  667.  
  668.  
  669.  
  670. //-----------------------------------------------------------------------------
  671. // Name: SaveSingleParameter
  672. // Desc:
  673. //-----------------------------------------------------------------------------
  674. VOID SaveSingleParameter( HWND hwndDlg, DWORD id, FLOAT * val, FLOAT min, FLOAT max, DWORD dwPrecision = 1 )
  675. {
  676.     TCHAR tszstr[MAX_PATH];
  677.  
  678.     DWORD pos = ( DWORD ) SendMessage( GetDlgItem( hwndDlg, id + 2), TBM_GETPOS, 0, 0 );
  679.  
  680.     FLOAT percent = ( FLOAT ) ( pos - DEFAULT_SLIDER_MIN ) / ( FLOAT ) ( DEFAULT_SLIDER_MAX - DEFAULT_SLIDER_MIN );
  681.     *val = percent * ( max - min ) + min;
  682.  
  683.     switch( dwPrecision )
  684.     {
  685.         case 0:
  686.             swprintf( tszstr, L"%.0f", *val );
  687.             break;
  688.         case 1:
  689.             swprintf( tszstr, L"%.1f", *val );
  690.             break;
  691.         case 2:
  692.         default:
  693.             swprintf( tszstr, L"%.2f", *val );
  694.             break;
  695.     }
  696.  
  697.     SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr );
  698. }
  699.  
  700.  
  701.  
  702.  
  703. //-----------------------------------------------------------------------------
  704. // Name: LoadWaveformRadio
  705. // Desc:
  706. //-----------------------------------------------------------------------------
  707. VOID LoadWaveformRadio( HWND hwndDlg, LONG waveform, LONG triangle, LONG square, LONG sine )
  708. {
  709.     if( waveform == triangle )
  710.         CheckRadioButton( hwndDlg, IDC_RADIO_TRIANGLE, IDC_RADIO_SINE, IDC_RADIO_TRIANGLE );
  711.     else if( waveform == square )
  712.         CheckRadioButton( hwndDlg, IDC_RADIO_TRIANGLE, IDC_RADIO_SINE, IDC_RADIO_SQUARE );
  713.     else if( waveform == sine )
  714.         CheckRadioButton( hwndDlg, IDC_RADIO_TRIANGLE, IDC_RADIO_SINE, IDC_RADIO_SINE );
  715.  
  716.     if( triangle >= 0 )
  717.         EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_TRIANGLE ), TRUE );
  718.     if( square >= 0 )
  719.         EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SQUARE ), TRUE );
  720.     if( sine >= 0 )
  721.         EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SINE ), TRUE );
  722.  
  723.     EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_WAVEFORM ), ( triangle + square + sine != -3 ) );
  724. }
  725.  
  726.  
  727.  
  728.  
  729. //-----------------------------------------------------------------------------
  730. // Name: LoadPhaseRadio
  731. // Desc:
  732. //-----------------------------------------------------------------------------
  733. VOID LoadPhaseRadio( HWND hwndDlg, LONG phase, LONG neg180, LONG neg90, LONG zero, LONG pos90, LONG pos180 )
  734. {
  735.     for( int i = IDC_RADIO_NEG_180; i <= IDC_RADIO_180; i++ )
  736.         EnableWindow( GetDlgItem( hwndDlg, i ), TRUE );
  737.  
  738.     EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_PHASE), TRUE );
  739.  
  740.     if( phase == neg180 )
  741.         CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_NEG_180 );
  742.     else if( phase == neg90 )
  743.         CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_NEG_90 );
  744.     else if( phase == zero )
  745.         CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_ZERO );
  746.     else if( phase == pos90 )
  747.         CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_90 );
  748.     else if( phase == pos180 )
  749.         CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_180 );
  750. }
  751.  
  752.  
  753.  
  754.  
  755. //-----------------------------------------------------------------------------
  756. // Name: LoadParameterUI( )
  757. // Desc: loads the paramter ui for particular effect
  758. //-----------------------------------------------------------------------------
  759. VOID LoadParameterUI( HWND hwndDlg, DWORD dwFXType )
  760. {
  761.     TCHAR tszstr[MAX_PATH];
  762.  
  763.     // reset the parameter ui
  764.     ResetParameterUI( hwndDlg );
  765.  
  766.     swprintf( tszstr, L"Parameters for [ %s ]", g_tszFXNames[dwFXType] );
  767.     SetDlgItemText( hwndDlg, IDC_FRAME, tszstr );
  768.  
  769.     switch( dwFXType)
  770.     {
  771.         case eSFX_chorus:
  772.         {
  773.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Wet/Dry Mix (%)" ), g_lpFXManager->m_paramsChorus.fWetDryMix, DSFXCHORUS_WETDRYMIX_MIN, DSFXCHORUS_WETDRYMIX_MAX );
  774.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Depth (%)" ), g_lpFXManager->m_paramsChorus.fDepth, DSFXCHORUS_DEPTH_MIN, DSFXCHORUS_DEPTH_MAX );
  775.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Feedback (%)" ), g_lpFXManager->m_paramsChorus.fFeedback, DSFXCHORUS_FEEDBACK_MIN, DSFXCHORUS_FEEDBACK_MAX );
  776.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Frequency (Hz)" ), g_lpFXManager->m_paramsChorus.fFrequency, DSFXCHORUS_FREQUENCY_MIN, DSFXCHORUS_FREQUENCY_MAX );
  777.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Delay (ms)" ), g_lpFXManager->m_paramsChorus.fDelay, DSFXCHORUS_DELAY_MIN, DSFXCHORUS_DELAY_MAX );
  778.             LoadWaveformRadio( hwndDlg, g_lpFXManager->m_paramsChorus.lWaveform, DSFXCHORUS_WAVE_TRIANGLE, -1, DSFXCHORUS_WAVE_SIN );
  779.             LoadPhaseRadio( hwndDlg, g_lpFXManager->m_paramsChorus.lPhase, DSFXCHORUS_PHASE_NEG_180, DSFXCHORUS_PHASE_NEG_90, DSFXCHORUS_PHASE_ZERO, DSFXCHORUS_PHASE_90, DSFXCHORUS_PHASE_180 );
  780.             break;
  781.         }
  782.  
  783.         case eSFX_compressor:
  784.         {
  785.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Gain (dB)" ), g_lpFXManager->m_paramsCompressor.fGain, DSFXCOMPRESSOR_GAIN_MIN, DSFXCOMPRESSOR_GAIN_MAX );
  786.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Attack (ms)" ), g_lpFXManager->m_paramsCompressor.fAttack, DSFXCOMPRESSOR_ATTACK_MIN, DSFXCOMPRESSOR_ATTACK_MAX );
  787.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Release (ms)" ), g_lpFXManager->m_paramsCompressor.fRelease, DSFXCOMPRESSOR_RELEASE_MIN, DSFXCOMPRESSOR_RELEASE_MAX );
  788.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Threshold (dB)" ), g_lpFXManager->m_paramsCompressor.fThreshold, DSFXCOMPRESSOR_THRESHOLD_MIN, DSFXCOMPRESSOR_THRESHOLD_MAX );
  789.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Ratio (x:1)" ), g_lpFXManager->m_paramsCompressor.fRatio, DSFXCOMPRESSOR_RATIO_MIN, DSFXCOMPRESSOR_RATIO_MAX );
  790.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME6, TEXT( "Predelay (ms)" ), g_lpFXManager->m_paramsCompressor.fPredelay, DSFXCOMPRESSOR_PREDELAY_MIN, DSFXCOMPRESSOR_PREDELAY_MAX, 0.05f, 2 );
  791.             break;
  792.         }
  793.  
  794.         case eSFX_distortion:
  795.         {
  796.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Gain (dB)" ), g_lpFXManager->m_paramsDistortion.fGain, DSFXDISTORTION_GAIN_MIN, DSFXDISTORTION_GAIN_MAX );
  797.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Edge (%)" ), g_lpFXManager->m_paramsDistortion.fEdge, DSFXDISTORTION_EDGE_MIN, DSFXDISTORTION_EDGE_MAX );
  798.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "PostEQ Center Freq (Hz)" ), g_lpFXManager->m_paramsDistortion.fPostEQCenterFrequency, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MIN, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MAX, 1.0f, 0 );
  799.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "PostEQ Bandwidth (Hz)" ), g_lpFXManager->m_paramsDistortion.fPostEQBandwidth, DSFXDISTORTION_POSTEQBANDWIDTH_MIN, DSFXDISTORTION_POSTEQBANDWIDTH_MAX, 1.0f, 0 );
  800.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "PreLowpass Cutoff (Hz)" ), g_lpFXManager->m_paramsDistortion.fPreLowpassCutoff, DSFXDISTORTION_PRELOWPASSCUTOFF_MIN, DSFXDISTORTION_PRELOWPASSCUTOFF_MAX, 1.0f, 0 );
  801.             break;
  802.         }
  803.  
  804.         case eSFX_echo:
  805.         {
  806.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Wet/Dry Mix (%)" ), g_lpFXManager->m_paramsEcho.fWetDryMix, DSFXECHO_WETDRYMIX_MIN, DSFXECHO_WETDRYMIX_MAX );
  807.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Feedback (%)" ), g_lpFXManager->m_paramsEcho.fFeedback, DSFXECHO_FEEDBACK_MIN, DSFXECHO_FEEDBACK_MAX );
  808.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Left Delay (ms)" ), g_lpFXManager->m_paramsEcho.fLeftDelay, DSFXECHO_LEFTDELAY_MIN, DSFXECHO_LEFTDELAY_MAX );
  809.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Right Delay (ms)" ), g_lpFXManager->m_paramsEcho.fRightDelay, DSFXECHO_RIGHTDELAY_MIN, DSFXECHO_RIGHTDELAY_MAX );
  810.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Pan Delay (bool)" ), (float) g_lpFXManager->m_paramsEcho.lPanDelay, DSFXECHO_PANDELAY_MIN, DSFXECHO_PANDELAY_MAX );
  811.             break;
  812.         }
  813.  
  814.         case eSFX_flanger:
  815.         {
  816.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Wet/Dry Mix (%)" ), g_lpFXManager->m_paramsFlanger.fWetDryMix, DSFXFLANGER_WETDRYMIX_MIN, DSFXFLANGER_WETDRYMIX_MAX );
  817.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Depth (%)" ), g_lpFXManager->m_paramsFlanger.fDepth, DSFXFLANGER_DEPTH_MIN, DSFXFLANGER_DEPTH_MAX );
  818.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Feedback (%)" ), g_lpFXManager->m_paramsFlanger.fFeedback, DSFXFLANGER_FEEDBACK_MIN, DSFXFLANGER_FEEDBACK_MAX );
  819.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Frequency (Hz)" ), g_lpFXManager->m_paramsFlanger.fFrequency, DSFXFLANGER_FREQUENCY_MIN, DSFXFLANGER_FREQUENCY_MAX, 0.01f, 2 );
  820.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Delay (ms)" ), g_lpFXManager->m_paramsFlanger.fDelay, DSFXFLANGER_DELAY_MIN, DSFXFLANGER_DELAY_MAX, 0.01f, 2 );
  821.             LoadWaveformRadio( hwndDlg, g_lpFXManager->m_paramsFlanger.lWaveform, DSFXFLANGER_WAVE_TRIANGLE, -1, DSFXFLANGER_WAVE_SIN );
  822.             LoadPhaseRadio( hwndDlg, g_lpFXManager->m_paramsFlanger.lPhase, DSFXFLANGER_PHASE_NEG_180, DSFXFLANGER_PHASE_NEG_90, DSFXFLANGER_PHASE_ZERO, DSFXFLANGER_PHASE_90, DSFXFLANGER_PHASE_180 );
  823.             break;
  824.         }
  825.  
  826.         case eSFX_gargle:
  827.         {
  828.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Rate (Hz)" ), ( FLOAT ) g_lpFXManager->m_paramsGargle.dwRateHz, ( FLOAT ) DSFXGARGLE_RATEHZ_MIN, ( FLOAT ) DSFXGARGLE_RATEHZ_MAX );
  829.             LoadWaveformRadio( hwndDlg, g_lpFXManager->m_paramsGargle.dwWaveShape, DSFXGARGLE_WAVE_TRIANGLE, DSFXGARGLE_WAVE_SQUARE, -1 );
  830.             break;
  831.         }
  832.  
  833.         case eSFX_parameq:
  834.         {
  835.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Center Freq (Hz)" ), g_lpFXManager->m_paramsParamEq.fCenter, DSFXPARAMEQ_CENTER_MIN, DSFXPARAMEQ_CENTER_MAX );
  836.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Bandwidth (Hz)" ), g_lpFXManager->m_paramsParamEq.fBandwidth, DSFXPARAMEQ_BANDWIDTH_MIN, DSFXPARAMEQ_BANDWIDTH_MAX );
  837.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Gain (dB)" ), g_lpFXManager->m_paramsParamEq.fGain, DSFXPARAMEQ_GAIN_MIN, DSFXPARAMEQ_GAIN_MAX );
  838.             break;
  839.         }
  840.  
  841.         case eSFX_reverb:
  842.         {
  843.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "In Gain (dB)" ), g_lpFXManager->m_paramsReverb.fInGain, DSFX_WAVESREVERB_INGAIN_MIN, DSFX_WAVESREVERB_INGAIN_MAX );
  844.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Reverb Mix (dB)" ), g_lpFXManager->m_paramsReverb.fReverbMix, DSFX_WAVESREVERB_REVERBMIX_MIN, DSFX_WAVESREVERB_REVERBMIX_MAX );
  845.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Reverb Time (ms)" ), g_lpFXManager->m_paramsReverb.fReverbTime, DSFX_WAVESREVERB_REVERBTIME_MIN, DSFX_WAVESREVERB_REVERBTIME_MAX );
  846.             LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "HighFreq RT Ratio (x:1)" ), g_lpFXManager->m_paramsReverb.fHighFreqRTRatio, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MIN, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MAX, 0.01f, 2 );
  847.             break;
  848.         }
  849.     }
  850. }
  851.  
  852.  
  853.  
  854.  
  855. //-----------------------------------------------------------------------------
  856. // Name: OnEffectChanged()
  857. // Desc: Called when the UI prompted an effect change
  858. //-----------------------------------------------------------------------------
  859. VOID OnEffectChanged( HWND hwndDlg )
  860. {
  861.     switch( g_dwCurrentFXType )
  862.     {
  863.         case eSFX_chorus:
  864.         {
  865.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsChorus.fWetDryMix, DSFXCHORUS_WETDRYMIX_MIN, DSFXCHORUS_WETDRYMIX_MAX );
  866.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsChorus.fDepth, DSFXCHORUS_DEPTH_MIN, DSFXCHORUS_DEPTH_MAX );
  867.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsChorus.fFeedback, DSFXCHORUS_FEEDBACK_MIN, DSFXCHORUS_FEEDBACK_MAX );
  868.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsChorus.fFrequency, DSFXCHORUS_FREQUENCY_MIN, DSFXCHORUS_FREQUENCY_MAX );
  869.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsChorus.fDelay, DSFXCHORUS_DELAY_MIN, DSFXCHORUS_DELAY_MAX );
  870.  
  871.             if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_TRIANGLE ) == BST_CHECKED )
  872.                 g_lpFXManager->m_paramsChorus.lWaveform = DSFXCHORUS_WAVE_TRIANGLE;
  873.             else
  874.                 g_lpFXManager->m_paramsChorus.lWaveform = DSFXCHORUS_WAVE_SIN;
  875.  
  876.             if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_180 ) == BST_CHECKED )
  877.                 g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_NEG_180;
  878.             else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_90 ) == BST_CHECKED )
  879.                 g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_NEG_90;
  880.             else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_ZERO ) == BST_CHECKED )
  881.                 g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_ZERO;
  882.             else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_90 ) == BST_CHECKED )
  883.                 g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_90;
  884.             else
  885.                 g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_180;
  886.  
  887.             if( g_lpFXManager->m_lpChorus )
  888.                 g_lpFXManager->m_lpChorus->SetAllParameters( &g_lpFXManager->m_paramsChorus );
  889.  
  890.             break;
  891.         }
  892.  
  893.         case eSFX_compressor:
  894.         {
  895.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsCompressor.fGain, DSFXCOMPRESSOR_GAIN_MIN, DSFXCOMPRESSOR_GAIN_MAX );
  896.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsCompressor.fAttack, DSFXCOMPRESSOR_ATTACK_MIN, DSFXCOMPRESSOR_ATTACK_MAX );
  897.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsCompressor.fRelease, DSFXCOMPRESSOR_RELEASE_MIN, DSFXCOMPRESSOR_RELEASE_MAX );
  898.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsCompressor.fThreshold, DSFXCOMPRESSOR_THRESHOLD_MIN, DSFXCOMPRESSOR_THRESHOLD_MAX );
  899.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsCompressor.fRatio, DSFXCOMPRESSOR_RATIO_MIN, DSFXCOMPRESSOR_RATIO_MAX );
  900.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME6, &g_lpFXManager->m_paramsCompressor.fPredelay, DSFXCOMPRESSOR_PREDELAY_MIN, DSFXCOMPRESSOR_PREDELAY_MAX, 2 );
  901.  
  902.             if( g_lpFXManager->m_lpCompressor )
  903.                 g_lpFXManager->m_lpCompressor->SetAllParameters( &g_lpFXManager->m_paramsCompressor );
  904.             break;
  905.         }
  906.  
  907.         case eSFX_distortion:
  908.         {
  909.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsDistortion.fGain, DSFXDISTORTION_GAIN_MIN, DSFXDISTORTION_GAIN_MAX );
  910.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsDistortion.fEdge, DSFXDISTORTION_EDGE_MIN, DSFXDISTORTION_EDGE_MAX );
  911.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsDistortion.fPostEQCenterFrequency, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MIN, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MAX, 0 );
  912.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsDistortion.fPostEQBandwidth, DSFXDISTORTION_POSTEQBANDWIDTH_MIN, DSFXDISTORTION_POSTEQBANDWIDTH_MAX, 0 );
  913.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsDistortion.fPreLowpassCutoff, DSFXDISTORTION_PRELOWPASSCUTOFF_MIN, DSFXDISTORTION_PRELOWPASSCUTOFF_MAX, 0 );
  914.  
  915.             if( g_lpFXManager->m_lpDistortion )
  916.                 g_lpFXManager->m_lpDistortion->SetAllParameters( &g_lpFXManager->m_paramsDistortion );
  917.             break;
  918.         }
  919.  
  920.         case eSFX_echo:
  921.         {
  922.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsEcho.fWetDryMix, DSFXECHO_WETDRYMIX_MIN, DSFXECHO_WETDRYMIX_MAX );
  923.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsEcho.fFeedback, DSFXECHO_FEEDBACK_MIN, DSFXECHO_FEEDBACK_MAX );
  924.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsEcho.fLeftDelay, DSFXECHO_LEFTDELAY_MIN, DSFXECHO_LEFTDELAY_MAX );
  925.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsEcho.fRightDelay, DSFXECHO_RIGHTDELAY_MIN, DSFXECHO_RIGHTDELAY_MAX );
  926.             float fTemp;
  927.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &fTemp, DSFXECHO_PANDELAY_MIN, DSFXECHO_PANDELAY_MAX );
  928.             g_lpFXManager->m_paramsEcho.lPanDelay = (LONG) fTemp;
  929.  
  930.             if( g_lpFXManager->m_lpEcho )
  931.                 g_lpFXManager->m_lpEcho->SetAllParameters( &g_lpFXManager->m_paramsEcho );
  932.             break;
  933.         }
  934.  
  935.         case eSFX_flanger:
  936.         {
  937.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsFlanger.fWetDryMix, DSFXFLANGER_WETDRYMIX_MIN, DSFXFLANGER_WETDRYMIX_MAX );
  938.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsFlanger.fDepth, DSFXFLANGER_DEPTH_MIN, DSFXFLANGER_DEPTH_MAX );
  939.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsFlanger.fFeedback, DSFXFLANGER_FEEDBACK_MIN, DSFXFLANGER_FEEDBACK_MAX );
  940.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsFlanger.fFrequency, DSFXFLANGER_FREQUENCY_MIN, DSFXFLANGER_FREQUENCY_MAX, 2 );
  941.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsFlanger.fDelay, DSFXFLANGER_DELAY_MIN, DSFXFLANGER_DELAY_MAX, 2 );
  942.  
  943.             if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_TRIANGLE ) == BST_CHECKED )
  944.                 g_lpFXManager->m_paramsFlanger.lWaveform = DSFXFLANGER_WAVE_TRIANGLE;
  945.             else
  946.                 g_lpFXManager->m_paramsFlanger.lWaveform = DSFXFLANGER_WAVE_SIN;
  947.  
  948.             if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_180 ) == BST_CHECKED )
  949.                 g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_NEG_180;
  950.             else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_90 ) == BST_CHECKED )
  951.                 g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_NEG_90;
  952.             else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_ZERO ) == BST_CHECKED )
  953.                 g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_ZERO;
  954.             else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_90 ) == BST_CHECKED )
  955.                 g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_90;
  956.             else
  957.                 g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_180;
  958.  
  959.             if( g_lpFXManager->m_lpFlanger )
  960.                 g_lpFXManager->m_lpFlanger->SetAllParameters( &g_lpFXManager->m_paramsFlanger );
  961.             break;
  962.         }
  963.  
  964.         case eSFX_gargle:
  965.         {
  966.             FLOAT fRateHz;
  967.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &fRateHz, DSFXGARGLE_RATEHZ_MIN, DSFXGARGLE_RATEHZ_MAX );
  968.             g_lpFXManager->m_paramsGargle.dwRateHz = (DWORD) fRateHz;
  969.  
  970.             if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_TRIANGLE ) == BST_CHECKED )
  971.                 g_lpFXManager->m_paramsGargle.dwWaveShape = DSFXGARGLE_WAVE_TRIANGLE;
  972.             else
  973.                 g_lpFXManager->m_paramsGargle.dwWaveShape = DSFXGARGLE_WAVE_SQUARE;
  974.  
  975.             if( g_lpFXManager->m_lpGargle )
  976.                 g_lpFXManager->m_lpGargle->SetAllParameters( &g_lpFXManager->m_paramsGargle );
  977.             break;
  978.         }
  979.  
  980.         case eSFX_parameq:
  981.         {
  982.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsParamEq.fCenter, DSFXPARAMEQ_CENTER_MIN, DSFXPARAMEQ_CENTER_MAX );
  983.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsParamEq.fBandwidth, DSFXPARAMEQ_BANDWIDTH_MIN, DSFXPARAMEQ_BANDWIDTH_MAX );
  984.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsParamEq.fGain, DSFXPARAMEQ_GAIN_MIN, DSFXPARAMEQ_GAIN_MAX );
  985.  
  986.             if( g_lpFXManager->m_lpParamEq )
  987.                 g_lpFXManager->m_lpParamEq->SetAllParameters( &g_lpFXManager->m_paramsParamEq );
  988.             break;
  989.         }
  990.  
  991.         case eSFX_reverb:
  992.         {
  993.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsReverb.fInGain, DSFX_WAVESREVERB_INGAIN_MIN, DSFX_WAVESREVERB_INGAIN_MAX );
  994.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsReverb.fReverbMix, DSFX_WAVESREVERB_REVERBMIX_MIN, DSFX_WAVESREVERB_REVERBMIX_MAX );
  995.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsReverb.fReverbTime, DSFX_WAVESREVERB_REVERBTIME_MIN, DSFX_WAVESREVERB_REVERBTIME_MAX );
  996.             SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsReverb.fHighFreqRTRatio, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MIN, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MAX, 2 );
  997.  
  998.             if( g_lpFXManager->m_lpReverb )
  999.                 g_lpFXManager->m_lpReverb->SetAllParameters( &g_lpFXManager->m_paramsReverb );
  1000.             break;
  1001.         }
  1002.     }
  1003. }
  1004.  
  1005.  
  1006.  
  1007.  
  1008. //-----------------------------------------------------------------------------
  1009. // Name: ValidateWaveFile()
  1010. // Desc: Open the wave file with the helper
  1011. //       class CWaveFile to make sure it is valid
  1012. //-----------------------------------------------------------------------------
  1013. HRESULT ValidateWaveFile( HWND hDlg, TCHAR* strFileName )
  1014. {
  1015.     HRESULT hr;
  1016.     CWaveFile waveFile;
  1017.  
  1018.     if( -1 == GetFileAttributes(strFileName) )
  1019.         return E_FAIL;
  1020.  
  1021.     // Verify the file is small
  1022.     HANDLE hFile = CreateFile( strFileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
  1023.     if( hFile != NULL )
  1024.     {
  1025.         // If you try to open a 100MB wav file, you could run out of system memory with this
  1026.         // sample cause it puts all of it into a large buffer.  If you need to do this, then 
  1027.         // see the "StreamData" sample to stream the data from the file into a sound buffer.
  1028.         DWORD dwFileSizeHigh = 0;
  1029.         DWORD dwFileSize = GetFileSize( hFile, &dwFileSizeHigh );
  1030.         CloseHandle( hFile );
  1031.  
  1032.         if( dwFileSizeHigh != 0 || dwFileSize > 1000000 )
  1033.         {
  1034.             SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("File too large.  You should stream large files.") );
  1035.             return E_FAIL;
  1036.         }
  1037.     }
  1038.  
  1039.     // Load the wave file
  1040.     if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) )
  1041.     {
  1042.         waveFile.Close();
  1043.         SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Bad wave file.") );
  1044.         return DXTRACE_ERR_MSGBOX( TEXT("Open"), hr );
  1045.     }
  1046.     else // The load call succeeded
  1047.     {
  1048.         WAVEFORMATEX* pwfx = waveFile.GetFormat();
  1049.         if( pwfx->wFormatTag != WAVE_FORMAT_PCM && pwfx->wFormatTag != WAVE_FORMAT_IEEE_FLOAT )
  1050.         {
  1051.             // Sound must be PCM or IEEE FLOAT when using DSBCAPS_CTRLFX
  1052.             SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Wave file must be PCM or IEEE FLOAT for effects control.") );
  1053.             SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") );
  1054.             return E_FAIL;
  1055.         }
  1056.  
  1057.         // Update the UI controls to show the sound as the file is loaded
  1058.         waveFile.Close();
  1059.  
  1060.         //EnablePlayUI( hDlg, TRUE );
  1061.         SetDlgItemText( hDlg, IDC_TEXT_FILENAME, strFileName );
  1062.         SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("File loaded.") );
  1063.         wcscpy( g_tszFilename, strFileName );
  1064.         return S_OK;
  1065.     }
  1066. }
  1067.  
  1068.  
  1069.  
  1070.  
  1071. //-----------------------------------------------------------------------------
  1072. // Name: CSoundFXManager( )
  1073. // Desc: constructor
  1074. //-----------------------------------------------------------------------------
  1075. CSoundFXManager::CSoundFXManager( )
  1076. {
  1077.     m_lpChorus = NULL;
  1078.     m_lpCompressor = NULL;
  1079.     m_lpDistortion = NULL;
  1080.     m_lpEcho = NULL;
  1081.     m_lpFlanger = NULL;
  1082.     m_lpGargle = NULL;
  1083.     m_lpParamEq = NULL;
  1084.     m_lpReverb = NULL;
  1085.  
  1086.     ZeroMemory( &m_paramsChorus, sizeof( DSFXChorus ) );
  1087.     ZeroMemory( &m_paramsCompressor, sizeof( DSFXCompressor ) );
  1088.     ZeroMemory( &m_paramsDistortion, sizeof( DSFXDistortion ) );
  1089.     ZeroMemory( &m_paramsFlanger, sizeof( DSFXFlanger ) );
  1090.     ZeroMemory( &m_paramsEcho, sizeof( DSFXEcho ) );
  1091.     ZeroMemory( &m_paramsGargle, sizeof( DSFXGargle ) );
  1092.     ZeroMemory( &m_paramsParamEq, sizeof( DSFXParamEq ) );
  1093.     ZeroMemory( &m_paramsReverb, sizeof( DSFXWavesReverb ) );
  1094.  
  1095.     m_dwNumFX = 0;
  1096.     ZeroMemory( m_rgFxDesc, sizeof( DSEFFECTDESC ) * eNUM_SFX );
  1097.     ZeroMemory( m_rgRefGuids, sizeof( GUID * ) * eNUM_SFX );
  1098.     ZeroMemory( m_rgPtrs, sizeof(LPVOID*) * eNUM_SFX );
  1099.     ZeroMemory( m_rgLoaded, sizeof( BOOL ) * eNUM_SFX );
  1100.  
  1101.     m_lpDSB8 = NULL;
  1102. }
  1103.  
  1104.  
  1105.  
  1106.  
  1107. //-----------------------------------------------------------------------------
  1108. // Name: ~CSoundFXManager( )
  1109. // Desc: destructor
  1110. //-----------------------------------------------------------------------------
  1111. CSoundFXManager::~CSoundFXManager( )
  1112. {
  1113.     // free any effects
  1114.     DisableAllFX( );
  1115.  
  1116.     // release the DirectSoundBuffer
  1117.     SAFE_RELEASE( m_lpDSB8 );
  1118. }
  1119.  
  1120.  
  1121.  
  1122.  
  1123. //-----------------------------------------------------------------------------
  1124. // Name: Initialize( )
  1125. // Desc: associates a DirectSoundBuffer with the manager, any effects
  1126. //       enabled in the old DirectSoundBuffer will be disabled,
  1127. //       and the effect objects released
  1128. //-----------------------------------------------------------------------------
  1129. HRESULT CSoundFXManager::Initialize( LPDIRECTSOUNDBUFFER lpDSB, BOOL bLoadDefaultParamValues )
  1130. {
  1131.     HRESULT hr;
  1132.  
  1133.     if( m_lpDSB8 )
  1134.     {
  1135.         // release the effect for the previously associated sound buffers
  1136.         DisableAllFX( );
  1137.         SAFE_RELEASE( m_lpDSB8 );
  1138.     }
  1139.  
  1140.     if( NULL == lpDSB )
  1141.         return S_OK;
  1142.  
  1143.     // get the interface
  1144.     if( FAILED( hr = lpDSB->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &m_lpDSB8 ) ) )
  1145.         return hr;
  1146.  
  1147.     if( bLoadDefaultParamValues )
  1148.         LoadDefaultParamValues( );
  1149.  
  1150.     return S_OK;
  1151. }
  1152.  
  1153.  
  1154.  
  1155.  
  1156. //-----------------------------------------------------------------------------
  1157. // Name: UnInitialize( )
  1158. // Desc: the manager goes back to default state, the effects params, however
  1159. //       will not be reset
  1160. //-----------------------------------------------------------------------------
  1161. HRESULT CSoundFXManager::UnInitialize( )
  1162. {
  1163.     Initialize( NULL, FALSE );
  1164.  
  1165.     return S_OK;
  1166. }
  1167.  
  1168.  
  1169.  
  1170.  
  1171. //-----------------------------------------------------------------------------
  1172. // Name: LoadDefaultParamValues( )
  1173. // Desc: loads the default param value for each effect
  1174. //-----------------------------------------------------------------------------
  1175. HRESULT CSoundFXManager::LoadDefaultParamValues( )
  1176. {
  1177.     DWORD i;
  1178.  
  1179.     if( NULL == m_lpDSB8 )
  1180.         return E_FAIL;
  1181.  
  1182.     for( i = eSFX_chorus; i < eNUM_SFX; i++ )
  1183.         SetFXEnable( i );
  1184.  
  1185.     ActivateFX( );
  1186.  
  1187.     if( m_lpChorus )
  1188.         m_lpChorus->GetAllParameters( &m_paramsChorus );
  1189.  
  1190.     if( m_lpCompressor )
  1191.         m_lpCompressor->GetAllParameters( &m_paramsCompressor );
  1192.  
  1193.     if( m_lpDistortion )
  1194.         m_lpDistortion->GetAllParameters( &m_paramsDistortion );
  1195.  
  1196.     if( m_lpEcho )
  1197.         m_lpEcho->GetAllParameters( &m_paramsEcho );
  1198.  
  1199.     if( m_lpFlanger )
  1200.         m_lpFlanger->GetAllParameters( &m_paramsFlanger );
  1201.  
  1202.     if( m_lpGargle )
  1203.         m_lpGargle->GetAllParameters( &m_paramsGargle );
  1204.  
  1205.     if( m_lpParamEq )
  1206.         m_lpParamEq->GetAllParameters( &m_paramsParamEq );
  1207.  
  1208.     if( m_lpReverb )
  1209.         m_lpReverb->GetAllParameters( &m_paramsReverb );
  1210.  
  1211.     DisableAllFX( );
  1212.  
  1213.     return S_OK;
  1214. }
  1215.  
  1216.  
  1217.  
  1218.  
  1219. //-----------------------------------------------------------------------------
  1220. // Name: LoadCurrentFXParameters
  1221. // Desc: loads the default param value for each effect
  1222. //-----------------------------------------------------------------------------
  1223. HRESULT CSoundFXManager::LoadCurrentFXParameters( )
  1224. {
  1225.     if( m_lpChorus )
  1226.         m_lpChorus->SetAllParameters( &m_paramsChorus );
  1227.  
  1228.     if( m_lpCompressor )
  1229.         m_lpCompressor->SetAllParameters( &m_paramsCompressor );
  1230.  
  1231.     if( m_lpDistortion )
  1232.         m_lpDistortion->SetAllParameters( &m_paramsDistortion );
  1233.  
  1234.     if( m_lpEcho )
  1235.         m_lpEcho->SetAllParameters( &m_paramsEcho );
  1236.  
  1237.     if( m_lpFlanger )
  1238.         m_lpFlanger->SetAllParameters( &m_paramsFlanger );
  1239.  
  1240.     if( m_lpGargle )
  1241.         m_lpGargle->SetAllParameters( &m_paramsGargle );
  1242.  
  1243.     if( m_lpParamEq )
  1244.         m_lpParamEq->SetAllParameters( &m_paramsParamEq );
  1245.  
  1246.     if( m_lpReverb )
  1247.         m_lpReverb->SetAllParameters( &m_paramsReverb );
  1248.  
  1249.     return S_OK;
  1250. }
  1251.  
  1252.  
  1253.  
  1254.  
  1255. //-----------------------------------------------------------------------------
  1256. // Name: SetFXEnable( )
  1257. // Desc: enables a sound effect for the sound buffer associated with this
  1258. //-----------------------------------------------------------------------------
  1259. HRESULT CSoundFXManager::SetFXEnable( DWORD esfxType )
  1260. {
  1261.     HRESULT hr;
  1262.  
  1263.     if( esfxType >= eNUM_SFX )
  1264.         return E_FAIL;
  1265.  
  1266.     if( m_rgLoaded[esfxType] )
  1267.         return S_FALSE;
  1268.     else
  1269.         m_rgLoaded[esfxType] = TRUE;
  1270.  
  1271.     switch ( esfxType )
  1272.     {
  1273.     case eSFX_chorus:
  1274.         hr = EnableGenericFX( GUID_DSFX_STANDARD_CHORUS,     IID_IDirectSoundFXChorus8,
  1275.                               (LPVOID*) &m_lpChorus );
  1276.         break;
  1277.     case eSFX_compressor:
  1278.         hr = EnableGenericFX( GUID_DSFX_STANDARD_COMPRESSOR, IID_IDirectSoundFXCompressor8,
  1279.                               (LPVOID*) &m_lpCompressor );
  1280.         break;
  1281.     case eSFX_distortion:
  1282.         hr = EnableGenericFX( GUID_DSFX_STANDARD_DISTORTION, IID_IDirectSoundFXDistortion8,
  1283.                               (LPVOID*) &m_lpDistortion );
  1284.         break;
  1285.     case eSFX_echo:
  1286.         hr = EnableGenericFX( GUID_DSFX_STANDARD_ECHO,       IID_IDirectSoundFXEcho8,
  1287.                               (LPVOID*) &m_lpEcho );
  1288.         break;
  1289.     case eSFX_flanger:
  1290.         hr = EnableGenericFX( GUID_DSFX_STANDARD_FLANGER,    IID_IDirectSoundFXFlanger8,
  1291.                               (LPVOID*) &m_lpFlanger );
  1292.         break;
  1293.     case eSFX_gargle:
  1294.         hr = EnableGenericFX( GUID_DSFX_STANDARD_GARGLE,     IID_IDirectSoundFXGargle8,
  1295.                               (LPVOID*) &m_lpGargle );
  1296.         break;
  1297.     case eSFX_parameq:
  1298.         hr = EnableGenericFX( GUID_DSFX_STANDARD_PARAMEQ,    IID_IDirectSoundFXParamEq8,
  1299.                               (LPVOID*) &m_lpParamEq );
  1300.         break;
  1301.     case eSFX_reverb:
  1302.         hr = EnableGenericFX( GUID_DSFX_WAVES_REVERB,        IID_IDirectSoundFXWavesReverb8,
  1303.                               (LPVOID*) &m_lpReverb );
  1304.         break;
  1305.     default:
  1306.         hr = E_FAIL;
  1307.         break;
  1308.     }
  1309.  
  1310.     return hr;
  1311. }
  1312.  
  1313.  
  1314.  
  1315.  
  1316. //-----------------------------------------------------------------------------
  1317. // Name: DisableAllFX( )
  1318. // Desc: disables all effect in the DirectSoundBuffer, and releases all effect
  1319. //       object.
  1320. //-----------------------------------------------------------------------------
  1321. HRESULT CSoundFXManager::DisableAllFX( )
  1322. {
  1323.     // release all effect interfaces created with this manager so far
  1324.     SAFE_RELEASE( m_lpChorus );
  1325.     SAFE_RELEASE( m_lpCompressor );
  1326.     SAFE_RELEASE( m_lpDistortion );
  1327.     SAFE_RELEASE( m_lpEcho );
  1328.     SAFE_RELEASE( m_lpFlanger );
  1329.     SAFE_RELEASE( m_lpGargle );
  1330.     SAFE_RELEASE( m_lpParamEq );
  1331.     SAFE_RELEASE( m_lpReverb );
  1332.  
  1333.     m_dwNumFX = 0;
  1334.     ZeroMemory( m_rgFxDesc, sizeof( DSEFFECTDESC ) * eNUM_SFX );
  1335.     ZeroMemory( m_rgRefGuids, sizeof( GUID * ) * eNUM_SFX );
  1336.     ZeroMemory( m_rgPtrs, sizeof(LPVOID*) * eNUM_SFX );
  1337.     ZeroMemory( m_rgLoaded, sizeof( BOOL ) * eNUM_SFX );
  1338.  
  1339.     if( NULL == m_lpDSB8 )
  1340.         return E_FAIL;
  1341.  
  1342.     // Buffer must be stopped before calling SetFx
  1343.     if( m_lpDSB8 )
  1344.         m_lpDSB8->Stop();
  1345.  
  1346.     // this removes all fx from the buffer
  1347.     m_lpDSB8->SetFX( 0, NULL, NULL );
  1348.  
  1349.     return S_OK;
  1350. }
  1351.  
  1352.  
  1353.  
  1354.  
  1355. //-----------------------------------------------------------------------------
  1356. // Name: ActivateFX( )
  1357. // Desc: activate the effects enabled from EnableFX( )
  1358. //-----------------------------------------------------------------------------
  1359. HRESULT CSoundFXManager::ActivateFX( )
  1360. {
  1361.     DWORD dwResults[eNUM_SFX];
  1362.     HRESULT hr;
  1363.     DWORD i;
  1364.  
  1365.     if( NULL == m_lpDSB8 )
  1366.         return E_FAIL;
  1367.  
  1368.     if( m_dwNumFX == 0 )
  1369.         return S_FALSE;
  1370.  
  1371.     if( FAILED( hr = m_lpDSB8->SetFX( m_dwNumFX, m_rgFxDesc, dwResults ) ) )
  1372.         return hr;
  1373.  
  1374.     // get reference to the effect object
  1375.     for( i = 0; i < m_dwNumFX; i++ )
  1376.         if( FAILED( hr = m_lpDSB8->GetObjectInPath( m_rgFxDesc[i].guidDSFXClass, 0, *m_rgRefGuids[i], m_rgPtrs[i] ) ) )
  1377.             return DXTRACE_ERR_MSGBOX( TEXT("GetObjectInPath"), hr );
  1378.  
  1379.     return S_OK;
  1380. }
  1381.  
  1382.  
  1383.  
  1384.  
  1385. //-----------------------------------------------------------------------------
  1386. // Name: EnableGenericFX( )
  1387. // Desc: given information, tries to enabled an effect in a DirectSoundBuffer8,
  1388. //       and tries obtain reference to effect interface
  1389. //-----------------------------------------------------------------------------
  1390. HRESULT CSoundFXManager::EnableGenericFX( GUID guidSFXClass, REFGUID rguidInterface, LPVOID * ppObj )
  1391. {
  1392.     // if an effect already allocated
  1393.     if( *ppObj )
  1394.         return S_FALSE;
  1395.  
  1396.     if( m_dwNumFX >= eNUM_SFX )
  1397.         return E_FAIL;
  1398.  
  1399.     // set the effect to be enabled
  1400.     ZeroMemory( &m_rgFxDesc[m_dwNumFX], sizeof(DSEFFECTDESC) );
  1401.     m_rgFxDesc[m_dwNumFX].dwSize         = sizeof(DSEFFECTDESC);
  1402.     m_rgFxDesc[m_dwNumFX].dwFlags        = 0;
  1403.     CopyMemory( &m_rgFxDesc[m_dwNumFX].guidDSFXClass, &guidSFXClass, sizeof(GUID) );
  1404.  
  1405.     m_rgRefGuids[m_dwNumFX] = &rguidInterface;
  1406.     m_rgPtrs[m_dwNumFX] = ppObj;
  1407.  
  1408.     m_dwNumFX++;
  1409.  
  1410.     return S_OK;
  1411. }